今天我們實作 gRPC services,觀察 gRPC services 是否可以在有 Istio 的協助下,真的能夠順利的對流量進行 load balance。
func (s *server) Echo(ctx context.Context, in *echo.EchoRequest) (*echo.EchoResponse, error) {
	return &echo.EchoResponse{ServerAddress: os.Getenv("POD_IP")}, nil
}
echoClient := echo.NewEchoServiceClient(conn)
for {
	time.Sleep(time.Second)
	resp, err := echoClient.Echo(context.Background(), &echo.EchoRequest{ClientAddress: currentPod})
	if err != nil {
		log.Println("Request err", err.Error())
	}
	log.Println("Resp:", resp.ServerAddress)
}
上面準備好了 client & server 的 .yaml,照著範例啟用會得到,一台負責 grpc request 觀察回傳的 client,與三台應該回傳各自不同 ip address 的 server。
確保 Istio 關閉
> kubectl label namespace default istio-injection=disable --overwrite=true
namespace/default labeled
Create ReplicaSet 後確保 Pod READY 1/1 (沒有 Istio proxy)
> kubectl create -f grpc-server.yaml
> kubectl create -f grpc-client.yaml
> kubectl get pods
NAME                          READY     STATUS    RESTARTS   AGE
grpc-client-974899fd8-wc9fj   1/1       Running   0          14s
grpc-server-df464f6bf-9pjkx   1/1       Running   0          22s
grpc-server-df464f6bf-sh2mg   1/1       Running   0          22s
grpc-server-df464f6bf-xs96w   1/1       Running   0          22s
觀察 grpc-client 呼叫到的 grpc-server ip
> kubectl logs -f grpc-client-974899fd8-wc9fj
2020/10/02 05:40:51 Current pod ip: 10.1.0.69
2020/10/02 05:40:52 Resp: 10.1.0.66
2020/10/02 05:40:53 Resp: 10.1.0.66
2020/10/02 05:40:54 Resp: 10.1.0.66
2020/10/02 05:40:55 Resp: 10.1.0.66
2020/10/02 05:40:56 Resp: 10.1.0.66
2020/10/02 05:40:57 Resp: 10.1.0.66
2020/10/02 05:40:58 Resp: 10.1.0.66
啟用 Istio
> kubectl label namespace default istio-injection=enable --overwrite
> istioctl install --set profile=demo
✔ Istio core installed                                                                                                                                                                                                    
✔ Istiod installed                                                                                                                                                                                                        
✔ Egress gateways installed                                                                                                                                                                                               
✔ Ingress gateways installed                                                                                                                                                                                              
✔ Installation complete
Create ReplicaSet 後確保 Pod READY 2/2 (有 Istio proxy)
> kubectl create -f grpc-server.yaml
> kubectl create -f grpc-client.yaml
> kubectl get pods
NAME                          READY     STATUS    RESTARTS   AGE
grpc-client-974899fd8-fkxpl   2/2       Running   0          21s
grpc-server-df464f6bf-78fwr   2/2       Running   0          2m2s
grpc-server-df464f6bf-mv59n   2/2       Running   0          2m2s
grpc-server-df464f6bf-wsv5r   2/2       Running   0          2m2s
觀察 grpc-client 呼叫到的 grpc-server ip
> kubectl logs grpc-client-974899fd8-fkxpl grpc-client
2020/10/02 06:03:35 Current pod ip: 10.1.0.83
2020/10/02 06:03:46 Resp: 10.1.0.80
2020/10/02 06:03:47 Resp: 10.1.0.81
2020/10/02 06:03:48 Resp: 10.1.0.82
2020/10/02 06:03:49 Resp: 10.1.0.80
2020/10/02 06:03:50 Resp: 10.1.0.81
我們很成功的看到,從 server side 回傳回來的 address,在沒有使用 Istio 時是固定的,而起用 Istio 後開始隨機出現三組不同的 address。整個過程十分簡單,僅需額外啟動 Istio,原本 app 的內容與部署的設定完全不需要額外調整。希望藉由這個簡單的例子,可以增強大家對 Istio load balance 的了解與信心。
於此特別推薦一下 Protoc容器化(rainforest) 這篇的做法,省去了我們在使用 grpc 時需建置 proto 環境的麻煩,真的很方便呦 